package top.jacktgq.cas.adder_accumulator;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 
 * @Title: AtomicAdder_Accumulator.java 
 * @Package top.jacktgq.cas.adder_accumulator 
 * @Description: 原子累加器的使用，以及性能测试
 * @author CandyWall   
 * @date 2020年11月3日 上午11:05:43 
 * @version V1.0
 */
public class AtomicAdder_Accumulator {
	public static void main(String[] args) {
		demo(
			() -> new AtomicLong(0),
			(adder) -> adder.getAndIncrement()
		);
		demo(
			() -> new LongAdder(),
			(adder) -> adder.increment()
		);
		
	}
	
	/**
	 * 
	 * @param adderSupplier	：提供原子累加器对象
	 * @param action		：执行累加操作
	 */
	private static <T> void demo(Supplier<T> adderSupplier, Consumer<T> action) {
		T adder = adderSupplier.get();
		List<Thread> threadList = new ArrayList<Thread>();
		//4个线程，每个线程累加50万次
		for(int i = 0; i < 4; i++) {
			threadList.add(new Thread(() -> {
				for(int j = 0; j < 50_0000; j++) {
					action.accept(adder);
				}
			}));
		}
		
		//开始时间
		long start = System.nanoTime();
		//启动所有线程
		threadList.forEach(t -> t.start());
		//等待所有线程执行结束
		threadList.forEach(t -> {
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});
		//结束时间
		long end = System.nanoTime();
		//打印结果
		System.out.println(adder + ", cost: " + (end - start) / 100_0000 + " ms");
	}
}
